#include "HP_TcpPackServer.h"
#include <iostream>
#include <vector>

CHPThreadPoolPtr g_ThreadPool = nullptr; // 创建线程池对象，使用智能指针管理，初始化为 nullptr

// 创建线程池
bool Create_ThreadPool() {
	g_ThreadPool = HP_Create_ThreadPool();

	// 参数: 初始线程数, 最大线程数, 策略 (如 TRP_FIXED), 栈大小 (0为默认)
	if (!g_ThreadPool->Start(0, 0, TRP_WAIT_FOR, 0))  return false;
	std::cout << "√√√ 业务线程池已成功启动 (实际工作线程数: " << g_ThreadPool->GetThreadCount() << ")." << std::endl;

    return true;

}

// 销毁线程池
void Destroy_ThreadPool() {
	g_ThreadPool->Stop();
	return;
}


void __HP_CALL MyTaskProc(struct TSocketTask* pTask) {
	// 从任务对象中获取所有信息
	ITcpServer* pSender = (ITcpServer*)pTask->sender;
	HP_CONNID connID = pTask->connID;
	LPCBYTE   pData = pTask->buf; // 根据头文件，成员名叫 buf
	int       iLength = pTask->bufLen; // 根据头文件，成员名叫 bufLen

	std::cout << ">> 数据到达事件 --> 客户端连接ID:" << connID << "   数据包长度:" << iLength << "字节" << std::endl;
	
	std::cout << "收到数据包的原始16进制数据:";
	for (int i = 0; i < iLength; i++) { printf("%02X ", pData[i]); }
	printf("\n");
	
	printf("去除前4字节校验位，数据(Utf8编码):%.*s\n", iLength - 4, (char*)(pData + 4));
	std::cout << "准备回应原数据包..." << std::endl;
	
	if (pSender->Send(connID, pData + 4, iLength - 4, 0)) {
		printf("回应原数据成功，回应长度:%d\n\n", iLength);
	}
	else {
		printf("回应数据失败，错误代码:%d\n\n", pSender->GetLastError());
	}

	return;

}



// 监听回调函数
EnHandleResult TcpServerListener::OnPrepareListen(ITcpServer* pSender, SOCKET soListen)
{
	TCHAR szAddress[46] = { 0 }; // 准备存储IP地址的缓冲区（IPv6最长45字符+结束符）
	int iAddressLen = 46; // 地址长度变量（初始设置为缓冲区大小）
	USHORT usPort = 0; // 端口变量
	
	pSender->GetListenAddress(szAddress, iAddressLen, usPort);
	std::cout << ">> 监听事件 --> 监听地址:" << szAddress << "   监听端口:" << usPort << std::endl;
	return HR_OK;
}

// 客户进入回调函数
EnHandleResult TcpServerListener::OnAccept(ITcpServer* pSender, CONNID dwConnID, UINT_PTR soClient)
{
	TCHAR szAddress[46] = { 0 }; // 准备存储IP地址的缓冲区（IPv6最长45字符+结束符）
	int iAddressLen = 46; // 地址长度变量（初始设置为缓冲区大小）
	USHORT usPort = 0; // 端口变量

	pSender->GetRemoteAddress(dwConnID, szAddress, iAddressLen, usPort);
	std::cout << ">> 客户进入事件 --> 客户端连接ID:" << dwConnID << "   客户端IP:" << szAddress << std::endl;
	return HR_OK;
}

// 握手事件回调
EnHandleResult TcpServerListener::OnHandShake(ITcpServer* pSender, CONNID dwConnID)
{
	TCHAR szAddress[46] = { 0 }; // 准备存储IP地址的缓冲区（IPv6最长45字符+结束符）
	int iAddressLen = 46; // 地址长度变量（初始设置为缓冲区大小）
	USHORT usPort = 0; // 端口变量

	pSender->GetRemoteAddress(dwConnID, szAddress, iAddressLen, usPort);
	std::cout << ">> 握手事件 --> 客户端连接ID:" << dwConnID << "   客户端IP:" << szAddress << std::endl;
	return HR_OK;
}

// 数据到达事件回调
EnHandleResult TcpServerListener::OnReceive(ITcpServer* pSender, CONNID dwConnID, const BYTE* pData, int iLength)
{
	// 创建一个 SocketTask 对象，让 HP-Socket 帮我们复制数据 (TBT_COPY)
	HP_LPTSocketTask pTask = HP_Create_SocketTaskObj(MyTaskProc, pSender, dwConnID, pData, iLength, TBT_COPY, 0, 0);
	if (!pTask) {
		std::cout << "XXX OnReceive 错误: 创建任务失败 (内存不足?), ConnID=" << dwConnID << std::endl;
		return HR_ERROR; // 返回错误，服务器将断开此连接
	}

	// 使用 AddTask 将任务提交到线程池，永不阻塞
	// HP_SocketTask_Process 是一个内置的包装器，它会调用 MyTaskProc 并自动销毁 pTask
	if (!g_ThreadPool->Submit(pTask, INFINITE)) {
		std::cout << "XXX OnReceive 错误: 提交任务到线程池失败 (队列已满?), ConnID=" << dwConnID << std::endl;
		HP_Destroy_SocketTaskObj(pTask);  // 提交失败，必须手动销毁任务对象
		return HR_ERROR; // 返回错误，服务器将断开此连接
	}
	// 任务已成功分发，I/O 线程立即返回 HR_OK，保持连接
	return HR_OK;
}

// 数据发送完成事件回调
EnHandleResult TcpServerListener::OnSend(ITcpServer* pSender, CONNID dwConnID, const BYTE* pData, int iLength)
{
	std::cout << ">> 数据发送完成事件 --> 客户端连接ID:" << dwConnID << ", 长度: " << iLength << std::endl;
	return HR_OK;
}

// 客户端关闭事件回调
EnHandleResult TcpServerListener::OnClose(ITcpServer* pSender, CONNID dwConnID, EnSocketOperation enOperation, int iErrorCode)
{
	std::cout << ">> 客户端关闭事件 --> 客户端连接ID:" << dwConnID << std::endl << std::endl;
	return HR_OK;
}


// 服务器关闭事件回调
EnHandleResult TcpServerListener::OnShutdown(ITcpServer* pSender)
{
	std::cout << ">> 服务器关闭事件!" << std::endl;
	return HR_OK;
}

